package br.edu.ufcg.splab.techniques.reduction;

import static org.junit.Assert.assertTrue;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import br.edu.ufcg.splab.core.InterfaceGenerate;
import br.edu.ufcg.splab.core.InterfaceGraph;
import br.edu.ufcg.splab.core.graph.Tree;
import br.edu.ufcg.splab.exceptions.LTSBTException;
import br.edu.ufcg.splab.generator.ConvertGraphToTree;
import br.edu.ufcg.splab.generator.TestCase;
import br.edu.ufcg.splab.generator.TestCaseGenerator;
import br.edu.ufcg.splab.generator.TestSuite;
import br.edu.ufcg.splab.parser.GraphToAnnotatedGraphParser;
import br.edu.ufcg.splab.techniques.reduction.requirement.InterfaceRequirement;
import br.edu.ufcg.splab.techniques.reduction.requirement.Requirement;
import br.edu.ufcg.splab.techniques.reduction.requirement.RequirementTracer;
import br.edu.ufcg.splab.techniques.reduction.requirement.TransitionsTracerGenerator;
import br.edu.ufcg.splab.util.Controller;
import br.edu.ufcg.splab.util.ReadTGF;


public class TransitionsRequirementTracerGeneratorTest {
	

	@Test
	public void testGetTracer(){
		try{
			List<InterfaceRequirement> expected_reqs = new ArrayList<InterfaceRequirement>();
			InterfaceRequirement r1 = new Requirement();
			r1.setLabel("(\"a\")");
			expected_reqs.add(r1);
			
			InterfaceRequirement r2 = new Requirement();
			r2.setLabel("(\"b\")");
			expected_reqs.add(r2);
			
			InterfaceRequirement r3 = new Requirement();
			r3.setLabel("(\"c\")");
			expected_reqs.add(r3);
			
			InterfaceRequirement r4 = new Requirement();
			r4.setLabel("(\"d\")");
			expected_reqs.add(r4);
			
			InterfaceRequirement r5 = new Requirement();
			r5.setLabel("(\"e\")");
			expected_reqs.add(r5);
			
			InterfaceRequirement r6 = new Requirement();
			r6.setLabel("(\"f\")");
			expected_reqs.add(r6);
			
			InterfaceRequirement r7 = new Requirement();
			r7.setLabel("(\"g\")");
			expected_reqs.add(r7);
			
			InterfaceRequirement r8 = new Requirement();
			r8.setLabel("(\"h\")");
			expected_reqs.add(r8);
			
			InterfaceRequirement r9 = new Requirement();
			r9.setLabel("(\"i\")");
			expected_reqs.add(r9);
			
			
			String graphPath = "./test-data/reduction/graph_test_reduction.tgf";
			
			ReadTGF parser = new ReadTGF();			
			InterfaceGraph graph = parser.getGraph(graphPath);
			
			InterfaceGenerate generator = new TestCaseGenerator();
			ConvertGraphToTree convertsGraphToTree = new ConvertGraphToTree();
			Tree tree = convertsGraphToTree.converterGraph(graph);
			tree.expand(1);
			TestSuite testSuite = generator.generate(tree);			
			TransitionsTracerGenerator transitions = new TransitionsTracerGenerator();
			RequirementTracer tracer = transitions.getTracer(testSuite);
				
			List<InterfaceRequirement> reqs = tracer.getRequirements();
			for(InterfaceRequirement req : expected_reqs){
				assertTrue(reqs.contains(req));
			}
						
			assertTrue(tracer.getTestCasesThatSatisfy(r1).size() == 6);
			assertTrue(tracer.getTestCasesThatSatisfy(r2).size() == 6);
			assertTrue(tracer.getTestCasesThatSatisfy(r3).size() == 5);
			assertTrue(tracer.getTestCasesThatSatisfy(r4).size() == 7);
			assertTrue(tracer.getTestCasesThatSatisfy(r5).size() == 10);
			assertTrue(tracer.getTestCasesThatSatisfy(r6).size() == 9);
			assertTrue(tracer.getTestCasesThatSatisfy(r7).size() == 11);
			assertTrue(tracer.getTestCasesThatSatisfy(r8).size() == 7);
			assertTrue(tracer.getTestCasesThatSatisfy(r9).size() == 7);
			
			List<TestCase> tcs_list1 = new ArrayList<TestCase>();
			List<TestCase> tcs_list2 = new ArrayList<TestCase>();
			List<TestCase> tcs_list3 = new ArrayList<TestCase>();
			List<TestCase> tcs_list4 = new ArrayList<TestCase>();
			List<TestCase> tcs_list5 = new ArrayList<TestCase>();
			List<TestCase> tcs_list6 = new ArrayList<TestCase>();
			List<TestCase> tcs_list7 = new ArrayList<TestCase>();
			List<TestCase> tcs_list8 = new ArrayList<TestCase>();
			List<TestCase> tcs_list9 = new ArrayList<TestCase>();
			
			tcs_list1.add(testSuite.get(0));
			tcs_list1.add(testSuite.get(1));
			tcs_list1.add(testSuite.get(2));
			tcs_list1.add(testSuite.get(3));
			tcs_list1.add(testSuite.get(4));
			tcs_list1.add(testSuite.get(5));
			
			tcs_list2.add(testSuite.get(0));
			tcs_list2.add(testSuite.get(1));
			tcs_list2.add(testSuite.get(2));
			tcs_list2.add(testSuite.get(3));
			tcs_list2.add(testSuite.get(4));
			tcs_list2.add(testSuite.get(5));
			
			tcs_list3.add(testSuite.get(0));
			tcs_list3.add(testSuite.get(3));
			tcs_list3.add(testSuite.get(7));
			tcs_list3.add(testSuite.get(9));
			tcs_list3.add(testSuite.get(11));
			
			tcs_list4.add(testSuite.get(6));
			tcs_list4.add(testSuite.get(7));
			tcs_list4.add(testSuite.get(8));
			tcs_list4.add(testSuite.get(9));
			tcs_list4.add(testSuite.get(10));
			tcs_list4.add(testSuite.get(11));
			tcs_list4.add(testSuite.get(12));
			
			tcs_list5.add(testSuite.get(2));
			tcs_list5.add(testSuite.get(3));
			tcs_list5.add(testSuite.get(4));
			tcs_list5.add(testSuite.get(4));
			tcs_list5.add(testSuite.get(5));	
			tcs_list5.add(testSuite.get(7));
			tcs_list5.add(testSuite.get(8));
			tcs_list5.add(testSuite.get(9));
			tcs_list5.add(testSuite.get(10));
			tcs_list5.add(testSuite.get(11));
			tcs_list5.add(testSuite.get(12));
			
			tcs_list6.add(testSuite.get(1));
			tcs_list6.add(testSuite.get(2));
			tcs_list6.add(testSuite.get(3));
			tcs_list6.add(testSuite.get(4));
			tcs_list6.add(testSuite.get(5));
			tcs_list6.add(testSuite.get(8));
			tcs_list6.add(testSuite.get(10));
			tcs_list6.add(testSuite.get(11));
			tcs_list6.add(testSuite.get(12));
			
			tcs_list7.add(testSuite.get(1));
			tcs_list7.add(testSuite.get(2));
			tcs_list7.add(testSuite.get(3));
			tcs_list7.add(testSuite.get(4));
			tcs_list7.add(testSuite.get(5));
			tcs_list7.add(testSuite.get(6));
			tcs_list7.add(testSuite.get(7));
			tcs_list7.add(testSuite.get(8));
			tcs_list7.add(testSuite.get(10));
			tcs_list7.add(testSuite.get(11));
			tcs_list7.add(testSuite.get(12));
			
			tcs_list8.add(testSuite.get(1));
			tcs_list8.add(testSuite.get(2));
			tcs_list8.add(testSuite.get(4));
			tcs_list8.add(testSuite.get(6));
			tcs_list8.add(testSuite.get(7));
			tcs_list8.add(testSuite.get(8));
			tcs_list8.add(testSuite.get(10));
			
			tcs_list9.add(testSuite.get(1));
			tcs_list9.add(testSuite.get(2));
			tcs_list9.add(testSuite.get(4));
			tcs_list9.add(testSuite.get(6));
			tcs_list9.add(testSuite.get(7));
			tcs_list9.add(testSuite.get(8));
			tcs_list9.add(testSuite.get(10));
			
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r1)){
				assertTrue(tcs_list1.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r2)){
				assertTrue(tcs_list2.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r3)){
				assertTrue(tcs_list3.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r4)){
				assertTrue(tcs_list4.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r5)){
				assertTrue(tcs_list5.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r6)){
				assertTrue(tcs_list6.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r7)){
				assertTrue(tcs_list7.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r8)){
				assertTrue(tcs_list8.contains(tc));
			}
			
			for(TestCase tc: tracer.getTestCasesThatSatisfy(r9)){
				assertTrue(tcs_list9.contains(tc));
			}
			
		
			List<TestCase> essentials = tracer.getEssentialTestCases();
			assertTrue(essentials.size() == 0);
			
			List<InterfaceRequirement> reqs_list1 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list2 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list3 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list4 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list5 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list6 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list7 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list8 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list9 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list10 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list11 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list12 = new ArrayList<InterfaceRequirement>();
			List<InterfaceRequirement> reqs_list13 = new ArrayList<InterfaceRequirement>();
			
					
//			 TC1: a,b,c
			reqs_list1.add(r1);
			reqs_list1.add(r2);
			reqs_list1.add(r3);
			
//			 TC2: a,b,f,g,h,i,g,h,i
			reqs_list2.add(r1);
			reqs_list2.add(r2);
			reqs_list2.add(r6);
			reqs_list2.add(r7);
			reqs_list2.add(r8);
			reqs_list2.add(r9);
			
//			 TC3: a,b,f,g,h,i,g,e
			reqs_list3.add(r1);
			reqs_list3.add(r2);
			reqs_list3.add(r6);
			reqs_list3.add(r7);
			reqs_list3.add(r8);
			reqs_list3.add(r9);
			reqs_list3.add(r5);
			
//			 TC4: a,b,f,g,e,c
			reqs_list4.add(r1);
			reqs_list4.add(r2);
			reqs_list4.add(r6);
			reqs_list4.add(r7);
			reqs_list4.add(r5);
			reqs_list4.add(r3);
			
//			 TC5: a,b,f,g,e,f,g,h,i
			reqs_list5.add(r1);
			reqs_list5.add(r2);
			reqs_list5.add(r6);
			reqs_list5.add(r7);
			reqs_list5.add(r5);
			reqs_list5.add(r8);
			reqs_list5.add(r9);
			
//			 TC6: a,b,f,g,e,f,g,e
			reqs_list6.add(r1);
			reqs_list6.add(r2);
			reqs_list6.add(r6);
			reqs_list6.add(r7);
			reqs_list6.add(r5);
			
//			 TC7: d,h,i,g,h,i,g
			reqs_list7.add(r4);
			reqs_list7.add(r8);
			reqs_list7.add(r9);
			reqs_list7.add(r7);			
			
//			 TC8: d,h,i,g,e,c
			reqs_list8.add(r4);
			reqs_list8.add(r8);
			reqs_list8.add(r9);
			reqs_list8.add(r7);
			reqs_list8.add(r5);
			reqs_list8.add(r3);
			
//			 TC9: d,h,i,g,e,f,g
			reqs_list9.add(r4);
			reqs_list9.add(r8);
			reqs_list9.add(r9);
			reqs_list9.add(r7);
			reqs_list9.add(r5);
			reqs_list9.add(r6);
			
//			 TC10: d,e,c
			reqs_list10.add(r4);
			reqs_list10.add(r5);
			reqs_list10.add(r3);
			
//			 TC11: d,e,f,g,h,i,g
			reqs_list11.add(r4);
			reqs_list11.add(r5);
			reqs_list11.add(r6);
			reqs_list11.add(r7);
			reqs_list11.add(r8);
			reqs_list11.add(r9);
			
//			 TC12: d,e,f,g,e,c
			reqs_list12.add(r4);
			reqs_list12.add(r5);
			reqs_list12.add(r6);
			reqs_list12.add(r7);
			reqs_list12.add(r3);
			
//			 TC13: d,e,f,g,e,f,g
			reqs_list13.add(r4);
			reqs_list13.add(r5);
			reqs_list13.add(r6);
			reqs_list13.add(r7);
					
			assertTrue(reqs_list1.size() == 3);
			assertTrue(reqs_list2.size() == 6);
			assertTrue(reqs_list3.size() == 7);
			assertTrue(reqs_list4.size() == 6);
			assertTrue(reqs_list5.size() == 7);
			assertTrue(reqs_list6.size() == 5);
			assertTrue(reqs_list7.size() == 4);
			assertTrue(reqs_list8.size() == 6);
			assertTrue(reqs_list9.size() == 6);
			assertTrue(reqs_list10.size() == 3);
			assertTrue(reqs_list11.size() == 6);
			assertTrue(reqs_list12.size() == 5);
			assertTrue(reqs_list13.size() == 4);
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(0))){
				assertTrue(reqs_list1.contains(re));
			}
		
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(1))){
				assertTrue(reqs_list2.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(2))){
				assertTrue(reqs_list3.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(3))){
				assertTrue(reqs_list4.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(4))){
				assertTrue(reqs_list5.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(5))){
				assertTrue(reqs_list6.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(6))){
				assertTrue(reqs_list7.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(7))){
				assertTrue(reqs_list8.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(8))){
				assertTrue(reqs_list9.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(9))){
				assertTrue(reqs_list10.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(10))){
				assertTrue(reqs_list11.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(11))){
				assertTrue(reqs_list12.contains(re));
			}
			
			for(InterfaceRequirement re: tracer.getRequirementsSatisfied(testSuite.get(12))){
				assertTrue(reqs_list13.contains(re));
			}			
			
		}catch (LTSBTException e){
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	@Test
	public void testGetTracer2(){
		try{
			String tgf = "./test-data/reduction/annotated_graph.tgf";
			
			ReadTGF read = new ReadTGF();			
			InterfaceGraph graph = read.getGraph(tgf);				
			GraphToAnnotatedGraphParser parser = new GraphToAnnotatedGraphParser();
			InterfaceGraph annotatedGraph = parser.graphContraction(graph);
			
			InterfaceGenerate generator = new TestCaseGenerator();
			ConvertGraphToTree convertsGraphToTree = new ConvertGraphToTree();
			Tree tree = convertsGraphToTree.converterGraph(annotatedGraph);
			tree.expand(3);
			TestSuite testSuite = generator.generate(tree);			
			Controller controller = new Controller();
			TestSuite validTS = controller.getValidTS(testSuite);
			
			TransitionsTracerGenerator transitions = new TransitionsTracerGenerator();
			RequirementTracer tracer = transitions.getTracer(validTS);
			
			for(TestCase tc: validTS){
				tracer.getRequirements().removeAll(tracer.getRequirementsSatisfied(tc));
			}
			assertTrue(tracer.getRequirements().isEmpty());
			
		}catch (LTSBTException e){
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

}
